// cf-231e
// 题意：给定一个联通仙人掌图，求两点间简单路径个数。(n, m<=10^5)
//
// 题解：用tarjan缩点，然后就是树上lca。
//
// run: $exec < input
// opt: 0
// flag: -g
#include <iostream>
#include <vector>
#include <stack>

int const maxn = 200100;
int head[maxn], end_point[2 * maxn], next[2 * maxn];
int alloc = 2;
int head1[maxn], end_point1[2 * maxn], next1[2 * maxn];
int alloc1 = 2;
// need for tarjan
int low[maxn], dfn[maxn], color[maxn];
bool instack[maxn];
int tick, color_tick;
std::stack<int> stk;

int count[maxn];
bool shrink[maxn];
int sum[maxn];
int n, m, k;

void add_edge(int u, int v)
{
	end_point[alloc] = v; next[alloc] = head[u]; head[u] = alloc++;
	end_point[alloc] = u; next[alloc] = head[v]; head[v] = alloc++;
}

void add_edge1(int u, int v)
{
	end_point1[alloc1] = v; next1[alloc1] = head1[u]; head1[u] = alloc1++;
	end_point1[alloc1] = u; next1[alloc1] = head1[v]; head1[v] = alloc1++;
}

void tarjan(int u, int parent)
{
	low[u] = dfn[u] = ++tick;
	stk.push(u);
	instack[u] = true;
	for (int p = head[u]; p; p = next[p]) {
		int v = end_point[p];
		if (v == parent) continue;
		if (!dfn[v]) {
			tarjan(v, u);
			low[u] = std::min(low[u], low[v]);
		} else if (instack[v])
			low[u] = std::min(low[u], dfn[v]);
	}
	if (low[u] == dfn[u]) {
		int t;
		++color_tick;
		do { t = stk.top(); stk.pop(); color[t] = color_tick; count[color_tick]++; }
		while (t != u);
	}
}

struct node
{
	int parent, rank, ancestor, color;
};
node every[maxn];

typedef int index;
typedef std::pair<int, index> node_type;
std::vector<std::pair<std::pair<int, int>, int> > input_pair(maxn);
std::vector<std::vector<node_type> > common_pair;

void make_set(int u)
{
	every[u].parent = u;
	every[u].rank = 0;
}

int find(int u)
{
	return (every[u].parent == u) ? u : (every[u].parent = find(every[u].parent));
}

void set_union(int u, int v)
{
	int uroot = find(u);
	int vroot = find(v);
	if (every[uroot].rank > every[vroot].rank)
		every[uroot].parent = vroot;
	else if (uroot != vroot) {
		every[vroot].parent = uroot;
		every[uroot].rank++;
	}
}

void tarjan_offline_lca(int u, int f)
{
	make_set(u);
	every[u].ancestor = u;
	for (int p = head1[u]; p; p = next1[p]) {
		int v = end_point1[p];
		if (v == f) continue;
		sum[v] = sum[u] + shrink[v];
		tarjan_offline_lca(v, u);
		set_union(u, v);
		every[find(u)].ancestor = u;
	}
	every[u].color = 1;

	for (int i = 0; i < (int)common_pair[u].size(); i++) {
		int v = common_pair[u][i].first, index = common_pair[u][i].second;
		if (every[v].color)
			input_pair[index].second = every[find(v)].ancestor;
	}
}

long long quick2(int b, long long mo)
{
	if (!b) return 1;
	auto ret = quick2(b / 2, mo);
	ret = (ret * ret) % mo;
	if (b & 1) ret = (ret * 2) % mo;
	return ret;
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin >> n >> m;
	for (int i = 0, x, y; i < m; i++) {
		std::cin >> x >> y;
		add_edge(x, y);
	}
	for (int i = 1; i <= n; i++) if (!dfn[i]) tarjan(i, -1);

	for (int i = 1; i <= n; i++) {
		if (count[color[i]] <= 1) continue;
		shrink[i] = true;
		shrink[color[i] + n] = true;
	}
	for (int i = 2; i < alloc; i += 2) {
		int u = end_point[i], v = end_point[i ^ 1];
		if (color[u] == color[v]) continue;
		if (shrink[u]) u = color[u] + n;
		if (shrink[v]) v = color[v] + n;
		add_edge1(u, v);
	}
	int root = 1;
	if (shrink[1]) { root = 2 * n + 1; add_edge1(root, color[1] + n); }

	common_pair.resize(2 * n + 2);
	std::cin >> k;
	for (int i = 0, x, y; i < k; i++) {
		std::cin >> x >> y;
		if (shrink[x]) x = color[x] + n;
		if (shrink[y]) y = color[y] + n;
		input_pair[i].first.first = x;
		input_pair[i].first.second = y;
		node_type tmp; tmp.second = i;
		tmp.first = y; common_pair[x].push_back(tmp);
		tmp.first = x; common_pair[y].push_back(tmp);
	}

	tarjan_offline_lca(root, -1);

	for (int i = 0; i < k; i++) {
		int u = input_pair[i].first.first, v = input_pair[i].first.second, c = input_pair[i].second;
		int ans = sum[u] + sum[v] - 2 * sum[c];
		if (shrink[c]) ans++;
		std::cout << quick2(ans, 1000000007) << '\n';
	}
}

